<template>
  <a-cascader
    v-bind="$attrs"
    :value="fakeValue"
    :options="treeData"
    :field-names="{
      children: 'children',
      label: labelField,
      value: valueField
    }"
    @change="onChange"
  />
</template>
<script>
import { getCurrentInstance, ref, watch } from 'vue'
import { buildTree, findInTree } from '@/utils/tree'
export default {
  name: 'SCascader',
  props: {
    code: String,
    url: String,
    labelField: {
      type: String,
      default: 'text'
    },
    valueField: {
      type: String,
      default: 'value'
    },
    keyField: {
      type: String,
      default: 'id'
    },
    parentKeyField: {
      type: String,
      default: 'parentId'
    },
    modelValue: {
      type: String,
      required: false
    }
  },
  emits: ['change', 'update:modelValue'],
  expose: [],
  setup(props, { emit, attrs }) {
    const fakeValue = ref([])
    const treeData = ref([])
    const context = getCurrentInstance()?.appContext.config.globalProperties
    const initValue = (val) => {
      fakeValue.value = []
      if (val) {
        const item = findInTree(treeData.value, props.valueField, val)
        if (item) {
          const _parents = []
          item._parents.forEach((t) => {
            _parents.push(t)
          })
          _parents.push(item[props.valueField])
          fakeValue.value = _parents
        }
      }
    }
    const loadData = () => {
      if (props.url) {
        context.$api.GET(props.url).then((res) => {
          if (res.data) {
            treeData.value = buildTree(
              res.data,
              props.parentKeyField,
              props.keyField,
              props.labelField,
              props.valueField
            )
            initValue(props.modelValue)
          }
        })
      } else if (props.code) {
        context.$api
          .GET('/data/tree/item/selectListByGroupId', { groupId: props.code })
          .then((res) => {
            if (res.data) {
              treeData.value = buildTree(
                res.data,
                props.parentKeyField,
                props.keyField,
                props.labelField,
                props.valueField
              )
              initValue(props.modelValue)
            }
          })
      }
    }

    const onChange = (value) => {
      let val = null
      if (value) {
        val = value[value.length - 1]
      }
      if (!attrs.hasOwnProperty('modelValue')) {
        initValue(val)
      }
      emit('update:modelValue', val)
      emit('change', val)
    }
    watch(
      () => props.url,
      (newVal, oldVal) => {
        fakeValue.value = []
        treeData.value = []
        loadData()
      }
    )
    watch(
      () => props.code,
      (newVal, oldVal) => {
        fakeValue.value = []
        treeData.value = []
        loadData()
      }
    )
    watch(
      () => props.modelValue,
      (newVal, oldVal) => {
        initValue(props.modelValue)
      }
    )
    initValue(props.modelValue)
    loadData()
    return { fakeValue, treeData, onChange, refreshData: loadData }
  }
}
</script>
